﻿using System.Security.Claims;
using EasyI18n.Api.Infrastructure.DataPersistence.MongoDb;
using EasyI18n.Api.Infrastructure.DataPersistence.MongoDb.Entities;
using EasyI18n.Api.Primary.Bases;
using EasyI18n.Api.Realization.Bases;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;

namespace EasyI18n.Api.Realization.Currents;

[AsType(LifetimeEnum.Scope, typeof(ICurrentSingle<SystemUser>))]
public class CurrentSystemUser(
    IHttpContextAccessor contextAccessor,
    IDocumentAccessor<SystemUser> userDocs,
    IDocumentAccessor<SystemUserLogin> loginDocs,
    IMemoryCache memoryCache) : ICurrentSingle<SystemUser>
{
    public async Task<SystemUser> QueryAsync(CancellationToken cancellationToken = default)
    {
        var objectId = await GetCurrentUserIdAsync();
        // if (objectId != default && memoryCache.TryGetValue<SystemUser>(objectId, out var userInfo))
        // {
        //     return userInfo!;
        // }
        //
        var userFilter =
            await userDocs.Collection.FindAsync(e => e.Id == objectId, cancellationToken: cancellationToken);
        var systemUser = await userFilter.FirstOrDefaultAsync(cancellationToken: cancellationToken);
        if (systemUser != null)
        {
            memoryCache.Set(objectId, systemUser, TimeSpan.FromMinutes(5));
        }
        else
        {
            throw new BusinessException("user not exists", BusinessExceptionTypeEnum.DataNotExists);
        }

        return systemUser!;
    }

    /**
    public async Task<ObjectId> GetCurrentUserIdAsync()
    {
        if (contextAccessor.HttpContext != null)
        {
            var id = contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
            var provider = contextAccessor.HttpContext.User.FindFirstValue("login_provider");
            if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(provider))
            {
                if (memoryCache.TryGetValue<ObjectId>($"{provider}:{id}", out var userId))
                {
                    return userId;
                }

                var userLoginFilter = await loginDocs.Collection.FindAsync(x => x.ProviderKey == id);
                var userLogin = await userLoginFilter.FirstOrDefaultAsync();
                if (userLogin != null)
                {
                    memoryCache.Set($"{provider}:{id}", userLogin.UserId, TimeSpan.FromHours(2));
                    return userLogin.Id;
                }
            }
        }

        return default;
    } **/
    
    public async Task<ObjectId> GetCurrentUserIdAsync()
    {
            var id = contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
            if (!string.IsNullOrWhiteSpace(id))
            {
                if (ObjectId.TryParse(id, out var userId))
                {
                   return await Task.FromResult(userId);
                }
            }

            throw new BusinessException("未登录", BusinessExceptionTypeEnum.UnauthorizedIdentity);
    }
    
}